/*****************************************************
 Copyright @ DusunIOT 2005-2023. All rights reserved.
 File Name: common_serial.h
 Author: yangwenxu
 Version: V1.0
 Date:2023年07月19日 星期三 10时03分21秒
 Description:串口的收发
 Other: none
 History: Created2023年07月19日 星期三 10时03分21秒 by:yangwenxu
*****************************************************/

#ifndef __COMMON_SERIAL_H__
#define __COMMON_SERIAL_H__

#include <termios.h>
#include "common_types.h"
#include "common_dbg_log.h"

/*
 * 系统用波特率宏定义
 */
#define SERIAL_BAUD_RATE_0             B0        /* 波特率为 0 */
#define SERIAL_BAUD_RATE_50            B50       /* 波特率为 50 */
#define SERIAL_BAUD_RATE_75            B75       /* 波特率为 75 */
#define SERIAL_BAUD_RATE_110           B110      /* 波特率为 110 */
#define SERIAL_BAUD_RATE_134           B134      /* 波特率为 134 */
#define SERIAL_BAUD_RATE_150           B150      /* 波特率为 150 */
#define SERIAL_BAUD_RATE_200           B200      /* 波特率为 200 */
#define SERIAL_BAUD_RATE_300           B300      /* 波特率为 300 */
#define SERIAL_BAUD_RATE_600           B600      /* 波特率为 600 */
#define SERIAL_BAUD_RATE_1200          B1200     /* 波特率为 1200 */
#define SERIAL_BAUD_RATE_1800          B1800     /* 波特率为 1800 */
#define SERIAL_BAUD_RATE_2400          B2400     /* 波特率为 2400 */
#define SERIAL_BAUD_RATE_4800          B4800     /* 波特率为 4800 */
#define SERIAL_BAUD_RATE_9600          B9600     /* 波特率为 9600 */
#define SERIAL_BAUD_RATE_19200         B19200    /* 波特率为 19200 */
#define SERIAL_BAUD_RATE_38400         B38400    /* 波特率为 38400 */
#define SERIAL_BAUD_RATE_57600         B57600    /* 波特率为 57600 */
#define SERIAL_BAUD_RATE_115200        B115200   /* 波特率为 115200 */
#define SERIAL_BAUD_RATE_230400        B230400   /* 波特率为 230400 */

/*
 * 系统用等待接收时间(ms)
 */
#define SERIAL_RECV_WAIT_10MS         (10)     /* 接收等待10ms */
#define SERIAL_RECV_WAIT_20MS         (20)     /* 接收等待20ms */
#define SERIAL_RECV_WAIT_30MS         (30)     /* 接收等待30ms */
#define SERIAL_RECV_WAIT_50MS         (50)     /* 接收等待50ms */
#define SERIAL_RECV_WAIT_100MS        (100)    /* 接收等待100ms */
#define SERIAL_RECV_WAIT_200MS        (200)    /* 接收等待200ms */
#define SERIAL_RECV_WAIT_300MS        (300)    /* 接收等待300ms */
#define SERIAL_RECV_WAIT_500MS        (500)    /* 接收等待500ms */
#define SERIAL_RECV_WAIT_1000MS       (1000)   /* 接收等待1000ms */
#define SERIAL_RECV_WAIT_2000MS       (2000)   /* 接收等待2000ms */
#define SERIAL_RECV_WAIT_3000MS       (3000)   /* 接收等待3000ms */
#define SERIAL_RECV_WAIT_5000MS       (5000)   /* 接收等待5000ms */


/*
 * 串口地址
 */
#define CONCAT(a, b) a ## b
 
#define COM0   "/dev/ttyCH343USB0"   /* 根据实际情况来定义 */
#define COM1   "/dev/......"         /* 根据实际情况来定义 */
#define COM2   "/dev/......"         /* 根据实际情况来定义 */
#define COM3   "/dev/......"         /* 根据实际情况来定义 */

#define COMX(n) CONCAT(COM, n)
/*
 * 串口默认配置信息宏定义
 */
#define SERIAL_BAUDRATE         B115200  /* 默认波特率为115200 */
#define SERIAL_DARABITS         8        /* 默认收发数据大小 8位 */
#define SERIAL_PARITY           'N'      /* 默认无奇偶校验位 */
#define SERIAL_STOPBITS         1        /* 默认数据停止位为 1个 */ 
#define SERIAL_SENDBITSMAX      256      /* 默认发送数据的大小 */
#define SERIAL_SERIALNAME_LEN   12       /* 默认串口名字的大小 */
#define SERIAL_AMX_BUF_LEN      1024     /* 最大缓冲区大小 */


/*
 * 函数返回错误信息宏定义
 */
typedef enum SERIAL_ERROR
{
    SERIAL_ERROR_OK                         = 0x0000,  /* */
    SERIAL_ERROR_INVALID_PARAMETER_VALUE    = 0x0001,  /* 参数不合法 */
    SERIAL_ERROR_OPEN_ERR                   = 0x0010,  /* 串口打开失败 */
    SERIAL_ERROR_SET_FLAG_ERR               = 0x0011,  /* 设置串口状态标记失败 */
    SERIAL_ERROR_NOT_DEV_TYPE               = 0x0100,  /* 串口不是终端 */
    SERIAL_ERROR_CONFIG_BACKUO_ERR          = 0x0101,  /* 串口信息备份失败 */
    SERIAL_ERROR_CLEAR_CACHE_ERR            = 0x0110,  /* 串口缓冲区清除失败 */
    SERIAL_ERROR_CONFIG_ERR                 = 0x0111,  /* 串口信息配置失败 */
    SERIAL_ERROR_SEND_ERR                   = 0x1000,  /* 数据发送失败 */
    SERIAL_ERROR_TIMEOUT                    = 0x1001,  /* select等待超时 */
    SERIAL_ERROR_RECV_ERR                   = 0x1010,  /* 数据接收失败 */
    SERIAL_ERROR_SELECT_ERR                 = 0x1100,  /* select接收失败 */
    SERIAL_ERROR_OVERSTEP_BUF_SIZE          = 0x1101,  /* 数据超出缓冲区大小 */
    SERIAL_ERROR_CLEAR_ALL_IO_DATA_ERR      = 0x1110,  /* 清除所有正在发生的I/O数据失败 */
    
}SERIAL_ERROR_E;
 
 /*
  * 函数日志信息打印
  */ 
#if 0

#define SERIAL_INFO(...)   (printf(DBG_LOG_FMT_BOLD(DBG_LOG_GREEN)  "[%s][INF]" DBG_LOG_FMT_CLEAR "%s::%15s() " , dbg_log_get_time_str(), DBG_FILE, DBG_FUNC), printf(__VA_ARGS__), printf("\n"))
#define SERIAL_PRIT(...)   (printf(DBG_LOG_FMT_BOLD(DBG_LOG_BLUE)   "[%s][DBG]" DBG_LOG_FMT_CLEAR "%s::%15s() " , dbg_log_get_time_str(), DBG_FILE, DBG_FUNC), printf(__VA_ARGS__), printf("\n"))
#define SERIAL_ERR(...)    (printf(DBG_LOG_FMT_BOLD(DBG_LOG_RED)    "[%s][ERR]" DBG_LOG_FMT_CLEAR "%s::%15s() " , dbg_log_get_time_str(), DBG_FILE, DBG_FUNC), printf(__VA_ARGS__), printf("\n"))
#define SERIAL_WARN(...)   (printf(DBG_LOG_FMT_BOLD(DBG_LOG_YELLOW) "[%s][WRN]" DBG_LOG_FMT_CLEAR "%s::%15s() " , dbg_log_get_time_str(), DBG_FILE, DBG_FUNC), printf(__VA_ARGS__), printf("\n"))

#else 

#define SERIAL_INFO(...)    DBG_LOG_INFO(__VA_ARGS__)
#define SERIAL_PRIT(...)    DBG_LOG_PRIT(__VA_ARGS__)
#define SERIAL_ERR(...)     DBG_LOG_ERR(__VA_ARGS__)
#define SERIAL_WARN(...)    DBG_LOG_WARN(__VA_ARGS__)

#endif

#if 0
#define serial_prit(...)    DBG_LOG(DBG_PRIT, DBG_LOG_SYSTEM_SERIAL_ID, DBG_LOG_HOST_APP_SYSTEM_MASK,...)
#define serial_info(...)    DBG_LOG(DBG_INFO, DBG_LOG_SYSTEM_SERIAL_ID, DBG_LOG_HOST_APP_SYSTEM_MASK,...)
#define serial_warn(...)    DBG_LOG(DBG_WARN, DBG_LOG_SYSTEM_SERIAL_ID, DBG_LOG_HOST_APP_SYSTEM_MASK,...)
#define serial_err(...)     DBG_LOG(DBG_ERR, DBG_LOG_SYSTEM_SERIAL_ID, DBG_LOG_HOST_APP_SYSTEM_MASK,...)
#define serial_crit(...)    DBG_LOG(DBG_CRIT, DBG_LOG_SYSTEM_SERIAL_ID, DBG_LOG_HOST_APP_SYSTEM_MASK,...)

#endif

#ifdef __cplusplus
    extern "C" {
#endif

typedef struct serial_t
{
    RB_INT8 Parity;                                  /* 校验 */
    RB_INT32 fd;                                     /* 串口标识符 */
    RB_INT32 Databits;                               /* 数据位 */
    RB_INT32 Stopbits;                               /* 结束位个数 */
    RB_INT32 mSend;                                  /* 发送数据的大小 */
    speed_t Baudrate;                                /* 波特率 */
    RB_INT8 SerialName[SERIAL_SERIALNAME_LEN];       /* 串口地址 */
    struct termios OldTermios;                       /* 存放串口配置的结构体 */
}SERIAL_INFO_T;  



/* @brief        打开串口，并进行配置。
 * @param[in]    devname 设备名字
 * @param[in]    baudrate 波特率     为0则默认配置为115200
 * @param[in]    conf串口的配置信息  为NULL则默认配置为8N1
 * @param[out]   serial 为SERIAL_INFO_T结构体，存储了串口的一些配置信息
 * return        小于0为配置失败，其余为串口描述符
 *               SERIAL_ERROR_INVALID_PARAMETER_VALUE  参数不合法
 *               SERIAL_ERROR_OPEN_ERR                 串口打开失败
 *               SERIAL_ERROR_SET_FLAG_ERR             设置串口状态标记失败
 *               SERIAL_ERROR_NOT_DEV_TYPE             串口不是终端
 *               SERIAL_ERROR_CONFIG_BACKUO_ERR        串口配置信息备份失败（将结果保留，还原设置时可以用到）
 *               SERIAL_ERROR_CONFIG_BACKUO_ERR        串口配置导出失败（用于设置新的参数）
 *               SERIAL_ERROR_CLEAR_CACHE_ERR          串口缓冲区清除失败
 *               SERIAL_ERROR_CONFIG_ERR               串口配置信息失败
 */
RB_INT32 serial_open(SERIAL_INFO_T *serial, RB_INT8 *devname, speed_t baudrate, RB_INT8 *conf);

/* @brief        关闭串口.并还原串口参数。
 * @param[in]    serial 为SERIAL_INFO_T结构体，存储了串口的一些配置信息
 * @param[out]   无
 * return        SERIAL_ERROR_OK                       清除成功
 *               SERIAL_ERROR_INVALID_PARAMETER_VALUE  参数不合法
 *               SERIAL_ERROR_CLEAR_ALL_IO_DATA_ERR    串口数据清除失败
 *               SERIAL_ERROR_CONFIG_ERR               串口参数还原失败
 */
RB_INT32 serial_close(SERIAL_INFO_T *serial);

/* @brief        发送函数
 * @param[in]    serial 为SERIAL_INFO_T结构体，存储了串口的一些配置信息
 * @param[in]    sendBuf 要发送的字符串指针
 * @param[in]    sendBufLen 为发送字符串的大小
 * @param[out]   无
 * return        大于0 为最终发送的字节数
 *               SERIAL_ERROR_CONFIG_ERR               参数为 NULL 或 为负
 *               SERIAL_ERROR_SEND_ERR                 数据发送失败（或发送数据大小不匹配）
 */
RB_INT32 serial_send(SERIAL_INFO_T *serial, RB_UINT8 *sendBuf, RB_UINT32 sendBufLen);

/* @brief        接收函数
 * @param[in]    fd 串口文件描述符
 * @param[in]    recvBuf 要发送的字符串指针
 * @param[in]    recvBufLen 为发送字符串的大小
 * @param[in]    timeout为要等待的ms数，如果为0 则无限等待
 * @param[out]   sendBufLen : 发送buf
 * return        大于0 接收到的数据的大小
 *               SERIAL_ERROR_TIMEOUT                  等待超时
 *               SERIAL_ERROR_TIMEOUT                  参数为 NULL 或 为负
 *               SERIAL_ERROR_SELECT_ERR               select接收失败
 *               SERIAL_ERROR_RECV_ERR                 read函数接收失败
 *               SERIAL_ERROR_OVERSTEP_BUF_SIZE        超出缓冲区大小
 */
RB_UINT32 serial_recv(RB_INT32 fd, RB_INT8 *recvBuf, RB_UINT32 recvBufLen, RB_INT32 timeout, RB_INT32 tryOneDelayMs,RB_UINT32 *sendBufLen);

 
#ifdef __cplusplus
}
#endif

#endif // __COMMON_SERIAL_H__
